//selected by ALU_ctr (change at will)
`define ADD  4'b0111 // 2's compl add
`define ADDU 4'b0001 // unsigned add
`define SUB  4'b0010 // 2's compl subtract
`define SUBU 4'b0011 // unsigned subtract
`define AND  4'b0100 // bitwise OR
`define OR   4'b0101 // bitwise AND
`define XOR  4'b0110 // bitwise XOR
`define SLT  4'b1010 // set result=1 if less than 2's compl
`define SLTU 4'b1011 // set result=1 if less than unsigned
`define NOP  4'b0000 // do nothing

module control_sig (startPC,Zero,nPC_sel,RegWr,RegDst,ExtOp,ALUSrc,ALUctr,MemWr,MemtoReg,ShiftSig,Jump);
	input [31:0] startPC;
	input Zero;
	reg nPC_sel,RegWr,RegDst,ExtOp,ALUSrc,MemWr,MemtoReg,Jump;
	output nPC_sel,RegWr,RegDst,ExtOp,ALUSrc,MemWr,MemtoReg,Jump;
	output [1:0] ShiftSig;
	output [3:0] ALUctr;
	reg [1:0] ShiftSig;
	reg [3:0] ALUctr;
	
	always@(*)
	begin
		case(startPC[31:26])
			6'b000000:begin  //											
				case(startPC[5:0])
					6'b100000: begin ALUctr = `ADD; nPC_sel = 0; RegWr = 1; RegDst = 1; ALUSrc = 0; MemWr = 0; ShiftSig = 2'b00; MemtoReg = 0; Jump = 0; end //add		R-type
					6'b100001: begin ALUctr = `ADDU; nPC_sel = 0; RegWr = 1; RegDst = 1; ALUSrc = 0; MemWr = 0; ShiftSig = 2'b00;  MemtoReg = 0; Jump = 0; end //addu
					6'b100100: begin ALUctr = `AND; nPC_sel = 0; RegWr = 1; RegDst = 1; ALUSrc = 0; MemWr = 0; ShiftSig = 2'b00; MemtoReg = 0; Jump = 0; end //and
					6'b100101: begin ALUctr = `OR; nPC_sel = 0; RegWr = 1; RegDst = 1; ALUSrc = 0; MemWr = 0; ShiftSig = 2'b00; MemtoReg = 0; Jump = 0; end //or
					6'b101010: begin ALUctr = `SLT; nPC_sel = 0; RegWr = 1; RegDst = 1; ALUSrc = 0; MemWr = 0; ShiftSig = 2'b00; MemtoReg = 0; Jump = 0; end //slt
					6'b101011: begin ALUctr = `SLTU; nPC_sel = 0; RegWr = 1; RegDst = 1; ALUSrc = 0; MemWr = 0; ShiftSig = 2'b00; MemtoReg = 0; Jump = 0; end //sltu
					6'b000000: begin ALUctr = `NOP; nPC_sel = 0; RegWr = 1; RegDst = 1; ALUSrc = 0; MemWr = 0;  ShiftSig = 2'b01; MemtoReg = 0; Jump = 0; end //sll
					6'b000011: begin ALUctr = `NOP; nPC_sel = 0; RegWr = 1; RegDst = 1; ALUSrc = 0; MemWr = 0;  ShiftSig = 2'b10; MemtoReg = 0; Jump = 0; end //sra
					6'b000010: begin ALUctr = `NOP; nPC_sel = 0; RegWr = 1; RegDst = 1; ALUSrc = 0; MemWr = 0;  ShiftSig = 2'b11; MemtoReg = 0; Jump = 0; end //srl
					6'b100110: begin ALUctr = `XOR; nPC_sel = 0; RegWr = 1; RegDst = 1; ALUSrc = 0; MemWr = 0; ShiftSig = 2'b00; MemtoReg = 0; Jump = 0; end //xor
					6'b100010: begin ALUctr = `SUB; nPC_sel = 0; RegWr = 1; RegDst = 1; ALUSrc = 0; MemWr = 0; ShiftSig = 2'b00; MemtoReg = 0; Jump = 0; end //sub
					6'b100011: begin ALUctr = `SUB; nPC_sel = 0; RegWr = 1; RegDst = 1; ALUSrc = 0; MemWr = 0; ShiftSig = 2'b00; MemtoReg = 0; Jump = 0; end //subu
					6'b001100: $finish;//syscall	need to look at more																					R-type 
				endcase
			end
			6'b000010: begin ALUctr = `NOP; nPC_sel = 1; RegWr = 0; RegDst = 1; ALUSrc = 0; MemWr = 0; ShiftSig = 2'b00; MemtoReg = 0; Jump = 1; end //j
			6'b000011: begin ALUctr = `NOP; nPC_sel = 1; RegWr = 1; RegDst = 1; ALUSrc = 0; MemWr = 0; ShiftSig = 2'b00; MemtoReg = 0; Jump = 1; end  //jal	still need to look at  			J-type
			6'b000100: case(Zero) //beq
							1'b0: begin ALUctr = `SUB; nPC_sel = 0; RegWr = 0; RegDst = 0; ALUSrc = 0; MemWr = 0; ShiftSig = 2'b00; MemtoReg = 0; Jump = 0; end
							1'b1: begin ALUctr = `SUB; nPC_sel = 1; RegWr = 0; RegDst = 0; ALUSrc = 0; MemWr = 0; ShiftSig = 2'b00; MemtoReg = 0; Jump = 0; end
					   endcase
			6'b000101: case(Zero) //bne
							1'b0: begin ALUctr = `SUB; nPC_sel = 1; RegWr = 0; RegDst = 0; ALUSrc = 0; MemWr = 0; ShiftSig = 2'b00; MemtoReg = 0; Jump = 0; end
							1'b1: begin ALUctr = `SUB; nPC_sel = 0; RegWr = 0; RegDst = 0; ALUSrc = 0; MemWr = 0; ShiftSig = 2'b00; MemtoReg = 0; Jump = 0; end
					   endcase
			6'b001000: begin ALUctr = `ADD; nPC_sel = 0; RegWr = 1; RegDst = 0; ALUSrc = 1; ExtOp = 1; MemWr = 0; ShiftSig = 2'b00; MemtoReg = 0; Jump = 0; end //addi		I-type	
			6'b001001: begin ALUctr = `ADDU; nPC_sel = 0; RegWr = 1; RegDst = 0; ALUSrc = 1; ExtOp = 0; MemWr = 0; ShiftSig = 2'b00; MemtoReg = 0; Jump = 0; end //addiu
			6'b001100: begin ALUctr = `AND; nPC_sel = 0; RegWr = 1; RegDst = 0; ALUSrc = 1; ExtOp = 1; MemWr = 0; ShiftSig = 2'b00; MemtoReg = 0; Jump = 0; end //andi
			6'b001101: begin ALUctr = `OR; nPC_sel = 0; RegWr = 1; RegDst = 0; ALUSrc = 1; ExtOp = 1; MemWr = 0; ShiftSig = 2'b00; MemtoReg = 0; Jump = 0; end //ori
			6'b001110: begin ALUctr = `XOR; nPC_sel = 0; RegWr = 1; RegDst = 0; ALUSrc = 1; ExtOp = 1; MemWr = 0; ShiftSig = 2'b00; MemtoReg = 0; Jump = 0; end //xori
			6'b001010: begin ALUctr = `SLT; nPC_sel = 0; RegWr = 1; RegDst = 0; ALUSrc = 1; ExtOp = 1; MemWr = 0; ShiftSig = 2'b00; MemtoReg = 0; Jump = 0; end //slti
			6'b001011: begin ALUctr = `SLTU; nPC_sel = 0; RegWr = 1; RegDst = 0; ALUSrc = 1; ExtOp = 0; MemWr = 0; ShiftSig = 2'b00; MemtoReg = 0; Jump = 0; end //sltiu
			6'b101011: begin ALUctr = `NOP; nPC_sel = 0; RegWr = 0; RegDst = 0; ALUSrc = 1; ExtOp = 1; MemWr = 1; ShiftSig = 2'b00; MemtoReg = 0; Jump = 0; end //sw
			6'b100011: begin ALUctr = `NOP; nPC_sel = 0; RegWr = 1; RegDst = 0; ALUSrc = 1; ExtOp = 1; MemWr = 0; ShiftSig = 2'b00; MemtoReg = 1; Jump = 0; end //lw
			6'b011010: begin ALUctr = `NOP; nPC_sel = 0; RegWr = 1; RegDst = 0; ALUSrc = 1; ExtOp = 1; MemWr = 0; ShiftSig = 2'b00; MemtoReg = 0; Jump = 0; end //li
			6'b001111: begin ALUctr = `NOP; nPC_sel = 0; RegWr = 1; RegDst = 0; ALUSrc = 1; ExtOp = 1; MemWr = 0; ShiftSig = 2'b00; MemtoReg = 0; Jump = 0; end //lui		I-type
		endcase
	end
endmodule
